package qdu.edu.com.fushanf4.utils;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;

import java.io.IOException;

public class ConfigurationUtil {
    private static final Configuration conf = new Configuration();

    static {
        conf.set(UtilConstants.HDFS.LINK_HDFS, UtilConstants.HDFS.LINK_HDFS_VALUE);
    }

    public static Configuration getConf() {
        return conf;
    }

    public static Job getJob() throws IOException {
        return Job.getInstance(conf);
    }

    /**
     * 删除输出路径及其内部的文件
     * @param outputPath 传入要删除的输出路径
     * @return 删除结果，true表示删除成功或目录不存在，false表示出现异常
     */
    public static boolean deleteOutputPathAndFiles(String outputPath) throws IOException {
        FileSystem fs;
        if (checkPathIsError(new String[]{outputPath}, 1)) {
            return false;
        }
        Path path = new Path(outputPath);
        fs = FileSystem.get(conf);
        assert fs != null;
        if (fs.exists(path)) {
            fs.delete(path, true);
        }
        fs.close();
        return true;
    }

    /**
     * 用于设置文件的输入路径和输出路径，并确保输出前输出路径为空，并运行job
     * @param args 传输的路径的参数
     * @param job Job
     * @return 返回运行的结果，true表示成功，false表示发生异常
     */
    public static boolean setPathAndRunJob(String[] args, Job job) throws IOException {
        if (checkPathIsError(args, 2)) {
            return false;
        }
        // 删除已存在的输出路径
        assert deleteOutputPathAndFiles(args[1]);
        // 设置输入和输出路径
        FileInputFormat.addInputPath(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));

        // 提交
        try {
            return job.waitForCompletion(true);    // 不写System.exit()的原因：如果写它，就会直接结束程序，不能继续运行后面的测试程序，会导致测试出错 解决方法，写断言，确保返回值是true
        } catch (InterruptedException | ClassNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 判断路径字符串数组是否是错误的，例如空指针（数组是空指针或数组中的对象是空指针），长度不对，空内容
     * @param paths 路径字符串数组
     * @param length 正确的字符串数组长度
     * @return 如果有错误，返回true；如果没有错误，返回false
     */
    private static boolean checkPathIsError(String[] paths, int length) {
        // 检查数组是不是null
        if (paths == null) {
            System.out.println("路径字符串数组为空指针");
            return true;
        }
        // 检查路径个数
        if (paths.length != length) {
            System.out.println("路径的个数不对，应为" + length + "，实际为" + paths.length);
            return true;
        }
        // 检查数组内容
        for (String path : paths) {
            // 检查字符串对象是不是空指针
            if (path == null) {
                System.out.println("路径字符串为空指针");
                return true;
            }
            // 检查字符串内容是不是空
            if (path.equals("")) {
                System.out.println("路径中的内容为空");
                return true;
            }
        }
        return false;
    }
}
